package org.jprobe.utils;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

import org.jprobe.JProbeException;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;


/**
 *
 * XML operations methods factory
 *
 * @author Hussain Al-Mutawa
 * @version 1.0
 * @since 1.0
 */
public final class XmlUtils {
	/** this class should be initialized **/
	private XmlUtils(){super();}

	/**
	 * gets an XML DOM object
	 * @param file the file pointing to the XML document
	 * @return document object
	 * @throws ParserConfigurationException
	 * @throws IOException
	 * @throws SAXException
	 * @throws Exception if IOException/SAXException/ParserConfigurationException is thrown
	 */
	public static Document getDocument(final String file) throws JProbeException  {

		try{
			// Step 1: create a DocumentBuilderFactory
			final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

			// Step 2: create a DocumentBuilder
			final DocumentBuilder builder = dbf.newDocumentBuilder();

			// Step 3: parse the input file to get a Document object
			return builder.parse(new File(file));

		}catch(final Exception cause){
			throw new JProbeException(cause.getMessage(), cause);
		}
	}
	/**
	 * gets query result using XPath on an XML document
	 * @param document xml document
	 * @param query the xpath query expression
	 * @return list f nodes returned by the query expression
	 * @throws JProbeException if the expression is malformed, document is null or invalid
	 */
	public static NodeList xpath(final Document document,final String query) throws JProbeException {
		final XPathFactory factory = XPathFactory.newInstance();
		final XPath xpath = factory.newXPath();
		try{
			final XPathExpression expr = xpath.compile(query);
			return (NodeList) expr.evaluate(document, XPathConstants.NODESET);
		}catch(final Exception cause){
			throw new JProbeException(cause.getMessage(), cause);
		}
	}
	/**
	 * @see XmlUtils#xpath(Document, String)
	 * @param xmldoc the path of XmlDocument
	 * @param query the xPath query to get node list from XML document
	 * @return node list
	 * @throws JProbeException
	 */
	public static NodeList xpath(final String xmldoc,final String query) throws JProbeException{
		return xpath(getDocument(xmldoc), query);
	}
}
